import 'dart:io';

import 'package:fixnum/fixnum.dart';
import 'package:grpc/grpc.dart';
import 'package:member_center_sdk/core/sdk_enum.dart';
import 'package:member_center_sdk/grpc/client.pbgrpc.dart';
import 'package:member_center_sdk/grpc/common.pb.dart';
import 'package:member_center_sdk/grpc_impl/base_client.dart';
import 'package:member_center_sdk/grpc_impl/grpc_result.dart';
import 'package:member_center_sdk/grpc_impl/merchant_client_channel.dart';

class MerchantClient extends BaseClient {
  static MerchantClientChannel _channel;
  static MerchantApiClient _client;

  MerchantClient(String host, int port, int merchantId, String signKey)
      : super(host, port, () {
          _channel = MerchantClientChannel(host, port, merchantId, signKey,
              options: const ChannelOptions(
                  credentials: const ChannelCredentials.insecure()));
          _client = MerchantApiClient(_channel);
          return _channel;
        });

  Future<GrpcResult<GetMemberResponse>> getMember(int memberId) async {
    return await doAction((options) {
      return _client.getMember(GetMemberRequest()..memberId = Int64(memberId),
          options: options);
    });
  }

  Future<GrpcResult<GetMemberResponse>> getMemberByUserName(
      String userName) async {
    return await doAction((options) {
      return _client.getMemberByUserName(
          GetMemberByUserNameRequest()..userName = userName,
          options: options);
    });
  }

  Future<GrpcResult<CheckTokenResponse>> checkToken(String token) async {
    return await doAction((options) {
      return _client.checkToken(CheckTokenRequest()..token = token,
          options: options);
    });
  }

  Future<GrpcResult<AuthResponse>> pwdAuth(int type, String userName,
      String password, String deviceId, String deviceName) async {
    DeviceType deviceType =
        Platform.isIOS ? DeviceType.Ios : DeviceType.Android;
    return await doAction((options) {
      return _client.pwdAuth(
          PwdAuthRequest()
            ..userName = userName
            ..password = password
            ..type = type
            ..deviceId = deviceId
            ..deviceName = deviceName
            ..deviceType = deviceType.index,
          options: options);
    });
  }

  Future<GrpcResult<SendSmsResponse>> sendSms(
      String deviceId, int type, String phone) async {
    return await doAction((options) {
      return _client.sendSms(
          SendSmsRequest()
            ..deviceId = deviceId
            ..type = type
            ..phone = phone,
          options: options);
    });
  }

  Future<GrpcResult<AuthResponse>> smsAuth(
      String deviceName, String smsId, String code) async {
    DeviceType deviceType =
        Platform.isIOS ? DeviceType.Ios : DeviceType.Android;
    return await doAction((options) {
      return _client.smsAuth(
          SmsAuthRequest()
            ..deviceType = deviceType.index
            ..deviceName = deviceName
            ..smsId = smsId
            ..code = code,
          options: options);
    });
  }

  Future<GrpcResult<BoolValue>> checkParent(int memberId) async {
    return await doAction((options) {
      return _client.checkParent(MemberIdRequest()..memberId = Int64(memberId),
          options: options);
    });
  }

  Future<GrpcResult<AuthResponse>> weChatAuth(
      String deviceName, String deviceId, String wxJson) async {
    DeviceType deviceType =
        Platform.isIOS ? DeviceType.Ios : DeviceType.Android;
    return await doAction((options) {
      return _client.weChatAuth(
          WeChatAuthRequest()
            ..deviceType = deviceType.index
            ..deviceName = deviceName
            ..deviceId = deviceId
            ..json = wxJson,
          options: options);
    });
  }

  Future<GrpcResult<GetGroupResponse>> getGroupInfoList(
      List<String> tokenList) async {
    return await doAction((options) {
      var request = GetGroupByTokenRequest();
      request.tokens.addAll(tokenList);
      return _client.getGroupByToken(request, options: options);
    });
  }

  Future<GrpcResult<BoolValue>> combineAccount(String userName,String mainToken,
      List<String> combineTokens) async {
    return await doAction((options) {
      var request = CombinAccountRequest();
      request.userName=userName;
      request.mainToken=mainToken;
      request.combinTokens.addAll(combineTokens);
      return _client.combinAccount(request, options: options);
    });
  }
}
